import json
import requests
import os
from loguru import logger
from Functions.PhotoDownload.Select import Select


class PhotoDownloader(Select):
    # 将 gids 提取为类属性，方便修改
    GIDS = 2

    def __init__(self,
                 game_id: int,
                 forum_id: int,
                 page_size: int,
                 game_name: str = "",
                 forum_name: str = "",
                 cate_name: str = "",
                 download_use_name: bool = False,
                 path="miyoushe/photos/"
                 ):
        super().__init__()
        self.download_counter = 0
        self.forum_id = forum_id
        if self.forum_id is None:
            self.e = True
            print("This forum id can not use")
        else:
            self.e = False
        self.page_size = page_size
        if not download_use_name:
            self.path = path + f"{game_id}/{game_name}/"
        else:
            self.path = path + f"{game_name}/{forum_name}/{cate_name + '/' if cate_name != '' else ''}"
        self.config = self.read_config()
        # gids = 2数据最多，为最新回复目录， gids = 6 时最优秀，为热门目录
        self.url = fr"https://bbs-api.miyoushe.com/painter/wapi/getRecentForumPostList?forum_id={self.forum_id}&gids={self.GIDS}&is_good=false&page_size={self.page_size}&sort_type=1"
        print(self.url)

    def read_config(self):
        """
        读取配置文件，如果文件存在则解析为 JSON 格式，否则返回空字典。
        """
        config_file = os.path.join(self.path, "config.json")
        if os.path.exists(config_file):
            try:
                with open(config_file, "r") as file:
                    return json.load(file)
            except json.JSONDecodeError:
                logger.error("Failed to decode config.json")
        return {}

    def write_config(self):
        """
        将当前配置写入配置文件。
        """
        config_file = os.path.join(self.path, "config.json")
        with open(config_file, "w") as file:
            json.dump(self.config, file, indent=4)

    def download_photo(self, url: str, name: str):
        """
        下载指定 URL 的图片，并将其保存到本地路径。
        如果图片已存在于配置中，则跳过下载。
        """
        try:
            logger.info(f"Downloading photo {name} from {url}")
            response = requests.get(url)
            response.raise_for_status()

            if not os.path.exists(self.path):
                os.makedirs(self.path, exist_ok=True)

            file_path = os.path.join(self.path, name)
            if name in self.config:
                logger.info(f"{name} already exists, skipping.")
                return True

            with open(file_path, "wb") as file:
                file.write(response.content)

            # update counter when download photo successfully.
            self.download_counter += 1

            self.config[name] = {
                "url": url,
                "name": name,
                "path": file_path,
            }
            self.write_config()

            logger.info(f"Downloaded photo {name} from {url} - {response.status_code} ok")
            return True
        except requests.RequestException as e:
            logger.error(f"Error downloading photo: {e}")
        except OSError as e:
            logger.error(f"Error saving photo: {e}")
        return False

    def get_photo_list(self, url: str):
        """
        从指定 URL 获取照片列表数据，并返回数据列表和最后一个 ID。
        如果请求失败或解析 JSON 数据出错，则返回空列表和 None。
        """
        try:
            response = requests.get(url)
            response.raise_for_status()
            data = response.json()
            # logger.debug(f"Received data: {data}")  # 增加调试日志
            return data["data"]["list"], data["data"]["last_id"]
        except requests.RequestException as e:
            logger.error(f"Error fetching data: {e}")
        except KeyError as e:
            logger.error(f"Error parsing JSON data: {e}")
        return [], None

    def run(self, num: int = 1):
        """
        运行下载器，循环下载指定次数的照片列表。
        """
        # update Download Counter, Photo Counter
        self.download_counter = 0
        self.photo_counter = 0
        if self.e:
            raise "Error url have bug " + self.url
        datas, last_id = self.get_photo_list(self.url)
        for _ in range(num):
            if datas:
                logger.info(f"len(datas) = {len(datas)}")
                self.photo_counter += len(datas)
                for data in datas:
                    # print(data)
                    self.download_photo(url=data["cover"]["url"], name=data["cover"]["url"].split("/")[-1])
                logger.info("Download process completed.")
            else:
                logger.warning("No data fetched.")
            if last_id and _ <= num:
                new_url = self.url + f"&last_id={last_id}"
                datas, last_id = self.get_photo_list(new_url)
        logger.success(
            f"Successfully downloaded {self.download_counter}/{self.photo_counter} <{(self.download_counter / self.photo_counter) * 100}%> photos.")


if __name__ == "__main__":
    select = Select()
    game_name = "崩坏：星穹铁道"
    forum_name = "同人图"
    forum_id = select.get_forum_id(game_name=game_name, forum_name=forum_name)
    downloader = PhotoDownloader(game_id=select.get_game_id(game_name),
                                 forum_id=forum_id,
                                 page_size=20,
                                 download_use_name=True,
                                 game_name=game_name,
                                 forum_name=forum_name,
                                 )
    downloader.run(4)
